import Api from '../../http/Api';
import { tokenInterceptor } from '../Interceptors';
import { AxiosResponse } from 'axios';

export type PageCondition =
  | {
      pageNum: number;
      pageSize: number;
    }
  | {
      noPage: true;
    };

export type OrderCondition = {
  columns: string[];
  mode: boolean;
};

export type RangeCondition<T> = {
  column: string;
  begin: T;
  end: T;
};

export type CategoryCondition<T = string | number> = {
  column: string;
  collection: T[];
};

export type TimeRangeCondition = RangeCondition<string>;
export type NumberRangeCondition = RangeCondition<number>;

export type ColumnCondition = {
  timeConditions?: TimeRangeCondition[];
  numberConditions?: NumberRangeCondition[];
  categoryConditions?: CategoryCondition[];
};

export interface QueryCondition<T> {
  query: Partial<T>;
  pageCondition?: PageCondition;
  orderConditions?: OrderCondition[];
  columnCondition?: ColumnCondition;
}

export type QueryAllCondition = Omit<QueryCondition<unknown>, 'query' | 'columnCondition'>;

export interface HttpModel<T> {
  code: number;
  msg: string;
  data: T;
}

export type DataResponse<T> = AxiosResponse<HttpModel<T>>;

export interface PageInfo<T> {
  records: T[];
  current: number;
  size: number;
  total: number;
  pages: number;
  searchCount: boolean;
}

export interface BaseModel<ID> {
  id: ID;
}

export interface ReadOnlyModel {
  readOnly: boolean;
}
export interface SystemModel {
  createTime: string;
  updateTime: string;
  createUser: string;
  updateUser: string;
}

export interface DefaultModel extends BaseModel<string>, ReadOnlyModel, SystemModel {}

export type IntModel = BaseModel<number>;

export type BigIntModel = BaseModel<string>;

export interface TimeModel extends BaseModel<string>, ReadOnlyModel {
  id: string;
  createTime: Date;
  updateTime: Date;
  createUser: string;
  updateUser: string;
}

export abstract class Service extends Api {
  public constructor() {
    super();
    this.create();
  }

  protected abstract create(): void;

  protected initTokenInstance = (baseURL: string): Api => {
    return this.initSingle(
      baseURL,
      {
        baseURL,
      },
      tokenInterceptor
    ) as Api;
  };
}
